#ifndef HUFFTREE_HPP_
#   define HUFFTREE_HPP_

#   include <map>
#   include "exc.hpp"
#   include "VRPTW.hpp"
#	include "Solution.hpp"
#   include <vector>


class HuffTree
{
    public:
		HuffTree() EXC_THROWER();
        HuffTree(const std::deque<unsigned>& inBase) EXC_THROWER();
        virtual ~HuffTree() {}
        
        HuffTree&       operator<<=(unsigned short inData) EXC_THROWER();
        
        HuffTree&		operator=(const HuffTree& inHuff);
        
        void		reset(const std::deque<unsigned>& inBase);
        void        display() const;
        void        printDot(const std::string& inFilename) const EXC_THROWER();
        
        void        updateLevels();
        
        void		execute();
        
        void        buildSolutions(VRPTW& inVRPTW, SolutionEval* inEval) const;
        
        void        permutLeaves(unsigned short inLeaf1, unsigned short inLeaf2) EXC_THROWER();
        
    protected:
		unsigned int	   heNNodes;
		unsigned int	   heNLeaves;
        unsigned int       heWeight[0xff];
        unsigned short     heData[0xff];    // si 0x1000 set, alors node, et addr fils gauche = data, fils droite = data + 1
        unsigned short     heLevel[0xff];
        unsigned short     heFather[0xff];
        unsigned           heMaxLevel;
        
        unsigned           heSize;
        
        std::multimap<unsigned, unsigned>   heIndexByLevel;
        std::map<unsigned short, unsigned>  heIndexByLeaf;
        std::deque<Tournee>				    heTournees;
        std::deque<TourneeEvalResult>		heEvals;
        
        void                permut(unsigned short   inIndex1, unsigned short    inIndex2);
};

#endif
